home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / bbsutils / smb_110a.arj / MAIL2SMB.C < prev    next >
C/C++ Source or Header  |  1994-03-28  |  8KB  |  308 lines

  1. /* MAIL2SMB.C */
  2.  
  3. /* Converts Synchronet Version 1 (proprietary) e-mail to SMB format */
  4.  
  5. /* The intention of this source code is an example of how to use the SMBLIB */
  6. /* library functions to access an SMB format message base.                    */
  7.  
  8. /* This program and source code are freeware. May be used in part or whole    */
  9. /* for any purpose without consent or notification of Digital Dynamics.     */
  10.  
  11. /* Digital Dynamics does request that developers that release products that */
  12. /* support the SMB format notify Digital Dynamics so the implementation     */
  13. /* and contact chapters in the technical specification may be updated.        */
  14.  
  15. #include "smblib.h"
  16. #include "crc32.h"
  17. #include <dos.h>
  18.  
  19. char sbbs[128];
  20.  
  21. /****************************************************************************/
  22. /* Updates 16-bit "rcrc" with character 'ch'                                */
  23. /****************************************************************************/
  24. void ucrc16(uchar ch, ushort *rcrc) {
  25.     ushort i, cy;
  26.     uchar nch=ch;
  27.  
  28. for (i=0; i<8; i++) {
  29.     cy=*rcrc & 0x8000;
  30.     *rcrc<<=1;
  31.     if (nch & 0x80) *rcrc |= 1;
  32.     nch<<=1;
  33.     if (cy) *rcrc ^= 0x1021; }
  34. }
  35.  
  36. /****************************************************************************/
  37. /* Returns 16-crc of string (not counting terminating NULL)                 */
  38. /****************************************************************************/
  39. ushort crc16(char *str)
  40. {
  41.     int     i=0;
  42.     ushort    crc=0;
  43.  
  44. ucrc16(0,&crc);
  45. while(str[i])
  46.     ucrc16(str[i++],&crc);
  47. ucrc16(0,&crc);
  48. ucrc16(0,&crc);
  49. return(crc);
  50. }
  51.  
  52.  
  53. /****************************************************************************/
  54. /* Truncates white-space chars off end of 'str' and terminates at first tab */
  55. /****************************************************************************/
  56. void truncsp(char *str)
  57. {
  58.     char c;
  59.  
  60. str[strcspn(str,"\t")]=0;
  61. c=strlen(str);
  62. while(c && (uchar)str[c-1]<=' ') c--;
  63. str[c]=0;
  64. }
  65.  
  66. /****************************************************************************/
  67. /* Converts an ASCII Hex string into an ulong                       */
  68. /****************************************************************************/
  69. ulong ahtoul(char *str)
  70. {
  71.     ulong l,val=0;
  72.  
  73. while((l=(*str++)|0x20)!=0x20)
  74.     val=(l&0xf)+(l>>6&1)*9+val*16;
  75. return(val);
  76. }
  77.  
  78. ulong hexplus(char *str)
  79. {
  80.      int i=0;
  81.  
  82. if(toupper(str[0])>'F') {
  83.     i=toupper(str[0])-'F';
  84.     str[0]='f'; }
  85. return(ahtoul(str)+(i*0x100));
  86. }
  87.  
  88. /****************************************************************************/
  89. /* Returns the length of the file in 'filespec'                             */
  90. /****************************************************************************/
  91. long flength(char *filespec)
  92. {
  93.     struct ffblk f;
  94.  
  95. if(findfirst(filespec,&f,0)==0)
  96.     return(f.ff_fsize);
  97. return(-1L);
  98. }
  99.  
  100. long fdate(char *filespec)
  101. {
  102.     struct ffblk f;
  103.     struct date fd;
  104.     struct time ft;
  105.  
  106. if(findfirst(filespec,&f,0)==NULL) {
  107.     fd.da_day=f.ff_fdate&31;
  108.     fd.da_mon=(f.ff_fdate>>5)&15;
  109.     fd.da_year=1980+((f.ff_fdate>>9)&127);
  110.     ft.ti_hour=(f.ff_ftime>>11)&31;
  111.     ft.ti_min=(f.ff_ftime>>5)&63;
  112.     ft.ti_sec=0;
  113.     return(dostounix(&fd,&ft)); }
  114. else return(NULL);
  115. }
  116.  
  117. /****************************************************************************/
  118. /* Returns the FidoNet address kept in str as ASCII.                        */
  119. /****************************************************************************/
  120. fidoaddr_t atofaddr(char *str)
  121. {
  122.     char *p;
  123.     fidoaddr_t addr;
  124.  
  125. addr.zone=addr.net=addr.node=addr.point=0;
  126. if((p=strchr(str,':'))!=NULL) {
  127.     addr.zone=atoi(str);
  128.     addr.net=atoi(p+1); }
  129. else {
  130.     addr.zone=1;
  131.     addr.net=atoi(str); }
  132. if(!addr.zone)                /* no such thing as zone 0 */
  133.     addr.zone=1;
  134. if((p=strchr(str,'/'))!=NULL)
  135.     addr.node=atoi(p+1);
  136. else {
  137.     addr.net=1;
  138.     addr.node=atoi(str); }
  139. if((p=strchr(str,'.'))!=NULL)
  140.     addr.point=atoi(p+1);
  141. return(addr);
  142. }
  143.  
  144.  
  145. int main(void)
  146. {
  147.     uchar    *p,str[128],from[128],to[128],subj[128],fname[128]
  148.             ,buf[SDT_BLOCK_LEN];
  149.     ushort    ftype,flen,xlat;
  150.     ushort    i,j,k,msgs,net,x;
  151.     ulong    length,crc;
  152.     FILE    *ixt,*stream;
  153.     smbmsg_t    msg;
  154.     smbstatus_t status;
  155.     fidoaddr_t    faddr;
  156.  
  157. p=getenv("SBBS");
  158. if(!p) {
  159.     printf("SBBS environment variable must be set.\r\n");
  160.     printf("example: SET SBBS=C:\\SBBS\r\n");
  161.     exit(1); }
  162.  
  163. strcpy(sbbs,p);
  164. strupr(sbbs);
  165. strcpy(smb_file,"MAIL");
  166.  
  167. smb_open(10);
  168.  
  169. sprintf(str,"%s\\INDX\\MAIL.IXT",sbbs);
  170. if((ixt=fopen(str,"rb"))==NULL) {
  171.     printf("error opening %s\r\n",str);
  172.     exit(1); }
  173.  
  174. if(!filelength(fileno(shd_fp)))
  175.     smb_create(0,2000,0,10);
  176.  
  177. smb_getstatus(&status);       // Initialized for first call to smb_addcrc()
  178.  
  179. for(i=0;!feof(ixt);i++) {
  180.     memset(&msg,0,sizeof(smbmsg_t));
  181.     memcpy(msg.hdr.id,"SHD\x1a",4);
  182.     msg.hdr.version=SMB_VERSION;
  183.  
  184.     if(!fgets(str,81,ixt))
  185.         break;
  186.     printf("%4u\r",i+1);
  187.     str[8]-=SP;
  188.     if(str[8]&(1<<1))
  189.         msg.idx.attr|=MSG_ANONYMOUS;
  190.     if(str[8]&16)
  191.         msg.hdr.auxattr|=MSG_FILEATTACH;
  192.     if(str[17]==SP)
  193.         msg.idx.attr|=MSG_READ;
  194.     msg.hdr.attr=msg.idx.attr;
  195.     str[8]=0;
  196.     strcpy(fname,str);
  197.     str[17]=0;
  198.     net=NET_NONE;
  199.  
  200.     msg.hdr.when_written.time=ahtoul(str+9);
  201.     strcpy(from,str+18);
  202.     truncsp(from);
  203.     p=strrchr(from,'@');
  204.     if(p) {
  205.         *p=0;
  206.         truncsp(from);
  207.         p++;
  208.         net=NET_FIDO;
  209.         smb_hfield(&msg,SENDERNETTYPE,sizeof(ushort),&net);
  210.         faddr=atofaddr(p);
  211.         smb_hfield(&msg,SENDERNETADDR,sizeof(fidoaddr_t),&faddr); }
  212.  
  213.     smb_hfield(&msg,SENDER,strlen(from),from);
  214.  
  215.     sprintf(str,"%.3s",fname+3);
  216.     j=hexplus(str);
  217.     if(j) {
  218.         sprintf(from,"%u",j);
  219.         msg.idx.from=atoi(from);
  220.         smb_hfield(&msg,SENDEREXT,strlen(from),from); }
  221.     else
  222.         msg.idx.from=0;
  223.  
  224.     if(!fgets(to,81,ixt))
  225.         break;
  226.     truncsp(to);
  227.     smb_hfield(&msg,RECIPIENT,strlen(to),to);
  228.  
  229.     sprintf(str,"%.3s",fname);
  230.     sprintf(to,"%lu",hexplus(str));
  231.     smb_hfield(&msg,RECIPIENTEXT,strlen(to),to);
  232.     msg.idx.to=atoi(to);
  233.  
  234.     if(!fgets(subj,81,ixt))
  235.         break;
  236.     truncsp(subj);
  237.     smb_hfield(&msg,SUBJECT,strlen(subj),subj);
  238.     strlwr(subj);
  239.     msg.idx.subj=crc16(subj);
  240.  
  241.     sprintf(str,"%s\\DATA\\MAIL\\%s.MSG",sbbs,fname);
  242.     length=flength(str);
  243.     msg.hdr.when_imported.time=fdate(str);
  244.     if(length<1L) {
  245.         printf("invalid length (%ld) for %s\n",length,str);
  246.         exit(1); }
  247.     if((stream=fopen(str,"rb"))==NULL) {
  248.         printf("\nError opening %s for read\n",str);
  249.         smb_freemsgmem(msg);
  250.         continue; }
  251.     fgets(str,81,stream);
  252.     length-=strlen(str);
  253.     fgets(str,81,stream);
  254.     length-=strlen(str);
  255.     fgets(str,81,stream);
  256.     length-=strlen(str);
  257.     fgets(str,81,stream);
  258.     length-=strlen(str);
  259.  
  260.     length+=2;    /* for translation string */
  261.  
  262.     if(smb_open_da(10)) {
  263.         printf("error opening %s.SDA\n",smb_file);
  264.         exit(1); }
  265.     msg.hdr.offset=smb_fallocdat(length,1);
  266.     fclose(sda_fp);
  267.     if(msg.hdr.offset && msg.hdr.offset<1L) {
  268.         printf("error %ld allocating blocks\r\n",msg.hdr.offset);
  269.         exit(1); }
  270.     fseek(sdt_fp,msg.hdr.offset,SEEK_SET);
  271.     xlat=XLAT_NONE;
  272.     fwrite(&xlat,2,1,sdt_fp);
  273.     crc=0xffffffffUL;
  274.     x=SDT_BLOCK_LEN-2;
  275.     while(!feof(stream)) {
  276.         memset(buf,NULL,x);
  277.         k=fread(buf,1,x,stream);
  278.         while(k && !buf[k-1]) k--;    /* take off NULLs, if any */
  279.         if((feof(stream) || k!=x) && buf[k-1]==LF && buf[k-2]==CR)
  280.             k-=2;
  281.         for(j=0;j<k;j++)
  282.             crc=ucrc32(buf[j],crc);
  283.         fwrite(buf,k,1,sdt_fp);
  284.         x=SDT_BLOCK_LEN; }
  285.     fclose(stream);
  286.  
  287.     crc=~crc;
  288.  
  289.  
  290.     j=smb_addcrc(status.max_crcs,crc,10);
  291.     if(j) {
  292.         if(j==1) {
  293.             printf("\nDuplicate message\n");
  294.             smb_freemsgmem(msg);
  295.             continue; }
  296.         printf("smb_addcrc returned %d\n",j);
  297.         exit(1); }
  298.  
  299.  
  300.     smb_dfield(&msg,TEXT_BODY,length);
  301.  
  302.     smb_addmsghdr(&msg,&status,1,10);
  303.     smb_freemsgmem(msg); }
  304.  
  305. return(0);
  306. }
  307.  
  308.